# --------------------------------------------------------------------------------
#  NoiseTube Web application
#  
#  Copyright (C) 2008-2010 SONY Computer Science Laboratory Paris
#  Portions contributed by Vrije Universiteit Brussel (BrusSense team), 2008-2011
# --------------------------------------------------------------------------------
#  This library is free software; you can redistribute it and/or modify it under
#  the terms of the GNU Lesser General Public License, version 2.1, as published
#  by the Free Software Foundation.
#  
#  This library is distributed in the hope that it will be useful, but WITHOUT
#  ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
#  FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more
#  details.
#  
#  You should have received a copy of the GNU Lesser General Public License along
#  with this library; if not, write to:
#    Free Software Foundation, Inc.,
#    51 Franklin Street, Fifth Floor,
#    Boston, MA  02110-1301, USA.
#  
#  Full GNU LGPL v2.1 text: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.txt
#  NoiseTube project source code repository: http://code.google.com/p/noisetube
# --------------------------------------------------------------------------------
#  More information:
#   - NoiseTube project website: http://www.noisetube.net
#   - Sony Computer Science Laboratory Paris: http://csl.sony.fr
#   - VUB BrusSense team: http://www.brussense.be
# --------------------------------------------------------------------------------
 
class TagsController < ApplicationController

  # /tags/time:tag_1+location:tag_2
  #
  caches_action :index

  def index
    #render :file => File.join( Rails.root, 'public', 'cache/tags.html'), :layout => false
    filter
  end

  def filter
    @tags_clouds = {}
    @tags=[]
    @tags+=params[:tags].split(",") unless params[:tags].nil?
    respond_to do |format|
      # RestFul: sematic representation
      format.html{
        %w(tags autoclienttags time_day time_week user_sensor user_calibrated time_season location_type location_district location_street loudness_value weather_general).each{ |context|
          @tags_clouds[context] = MeasurementsTag.tag_counts_by_context(context)
          #@tags_clouds.sort_by{|tag| tag.tag_name unless tag.blank?}  unless @tags_clouds.blank?
        }
        render :template=>"tags/filter.html.erb"
      }
      # geographical representation
      format.kml{
         #TODO Solve for kml request
      }
      end

  end
  # ---------------------------- old code --------------------------------------
  def index_slow
    filter
  end
  
  def filter_old
    @baseurl=root_url
    
    @tags=[]    
    @tags+=params[:tags].split(",") unless params[:tags].nil?
    
    respond_to do |format|

      # RestFul: sematic representation
      format.html{
        
        @tags_clouds={}
        %w(tags autoclienttags time_day time_week user_mobility user_sensor user_calibrated time_season location_type location_city location_district location_street loudness_value loudness_behavior weather_general weather_temperature weather_wind).each{ |semantic|

          tags=semantic_perspective(@tags,"#{semantic}")
          # sort by name
          @tags_clouds[semantic]=tags.sort_by{| tag|  tag.name }
        }
        render :template=>"tags/filter.html.erb"
      }

      # geographical representation
      format.kml{
        
        @measures=geographical_perspective(params)
        cond,joins=Measure.search_options(params)
        @tags_measure={}
        taggings=Tagging.find(:all, :joins=>"INNER JOIN measures ON taggings.taggable_id = measures.id INNER JOIN tags ON tags.id = taggings.tag_id", :conditions=>"measures.geom is not null and taggings.context='tags' and #{cond} ", :order=>"tags.name")

        unless taggings.empty?

          taggings.each{|tagging|
            name=tagging.tag.name
            if @tags_measure[name].nil?
              @tags_measure[name]={:taggings=>[], :count=>0}
            end
            @tags_measure[name][:taggings]<<tagging
            @tags_measure[name][:count]+=1
          }
        end
        render :template=>"tags/filter.kml.erb"
      }
               
      # #@ranges=Measure.by_range(measures) #render :template =>
      # "cities/map.kml.erb", :mimetype => :kml

  end
end

def legend
  @baseurl=root_url
  @box=params[:BBOX]
  @tags_type=params[:type_tags] || "tags"
  @tags=[]
  @tags=params[:exclude_tags].split(",") unless params[:exclude_tags].blank?
  respond_to do |format|
    format.kml{
    }
  end
    
end


  # ---------- visualize tag measure data
  #visualizes the measures
  def viz_measures
    @tagging = MeasurementsTag.find(params[:id])
    respond_to do |format|
      format.png{
        date_max=@tagging.created_at
        measures= @tagging.measures.collect { |measure|
            measure if (measure.made_at < date_max + 20) and (measure.made_at > date_max - 20)  #find(:all,:select=>"loudness", :conditions=>["made_at<? and made_at>?",date_max+20, (date_max-20)])
          }
        image=Measure.graph(measures)
        redirect_to image
      }
    end
  end

  # ----------------------- privates -------------------------
private

def geographical_count(tags)
  unless (tags.empty?)
    cond1=[]
    tags.each { |tag|
      context,name=tag.split(":")
      cond1<<"( taggings_tags.name = E'#{name}' and taggings.context='#{context}')"
    }
  end
  return Tagging.find_by_sql("SELECT * FROM taggings LEFT OUTER JOIN measures ON measures.id=taggings.taggable_id LEFT OUTER JOIN tags taggings_tags ON taggings_tags.id = taggings.tag_id WHERE measures.geom is not null and #{cond1.join(" OR ")} GROUP BY taggings.taggable_id HAVING COUNT(taggings.taggable_id) =#{cond1.size}")
  # #return Measure.find(:all, :conditions=>"measures.geom is not null and
  # measures.id IN (SELECT taggings.taggable_id FROM taggings LEFT OUTER JOIN
  # tags taggings_tags ON taggings_tags.id = taggings.tag_id WHERE
  # #{cond1.join(" OR ")} GROUP BY taggings.taggable_id HAVING
  # COUNT(taggings.taggable_id)
  # =#{cond1.size}) ")
end





def semantic_perspective(tags, general_context,limit=30)
  
  unless (tags.empty?)
    cond1=[]
    cond2=[]
    names=[]
    tags.each { |tag|
      context,name=tag.split(":")
      name=name.gsub(/\\/, '\&\&').gsub(/'/, "''")
      cond1<<"( tag_name = E'#{name}' and context='#{context}')"
      # remove the selected tags of the tag cloud 
      cond2<< " (not tag_name = E'#{name}' )"
      names<<name
    }

    cond="taggable_id IN (SELECT taggings.taggable_id FROM taggings LEFT OUTER JOIN tags ON tags.id = taggings.tag_id WHERE #{cond1.join(" OR ")} GROUP BY taggings.taggable_id HAVING COUNT(taggings.taggable_id) =#{cond1.size}) "

    # error
    cond+=" and #{cond2.join(" and ")}" unless cond2.empty?
      
  end
  unless cond.nil?
    Measure.tag_counts_on({:conditions=>cond, :order=>"count desc", :limit=>limit}, general_context)
  else
    Measure.tag_counts_on({:order=>"count desc", :limit=>limit}, general_context)
  end
end

  
end
